package com.imooc;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * 功能：加载manager工厂
* @ClassName: ManagerFactory 
* @Description: TODO 
* @author zyd
* @date 2017年12月12日 下午4:35:07
 */
public class ManagerFactory {

	//记录热加载类的加载信息
	private static final Map<String,LoadInfo> loadTimeMap = new HashMap<String, LoadInfo>();
	//要加载的类classpath
	public static final String CLASS_PATH = "F:/eclipse_mars_workspace/classloader_project/bin/";
	//实现热加载的类的全路径(包名+类名)
	public static final String MY_MANAGER = "com.imooc.MyManager";
	
	public static BaseManager getManager(String className){
		File loadFile = new File(CLASS_PATH+className.replace("\\.", "/")+".class");
		long lastModified = loadFile.lastModified();
		System.out.println(className+"111111111");
		System.out.println(lastModified);
		//loadTimeMap不包含className为key的loadInfo信息，证明这个类没有被加载，那么需要加载这个类到Jvm
		if(loadTimeMap.get(className)==null){
			load(className,lastModified);	
		}
		//加载的时间戳变化了，我们同样需要加载这个类到Jvm中
		else if(loadTimeMap.get(className).getLoadTime()!= lastModified){
			load(className,lastModified);	
		}
		
		return loadTimeMap.get(className).getManager();
	}

	private static void load(String className, long lastModified) {
		MyClassLoader myClassLoader = new MyClassLoader(CLASS_PATH);
		Class<?> loadClass = null;
		try {
			loadClass = myClassLoader.loadClass(className);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		BaseManager manager = newInstance(loadClass);
		LoadInfo loadInfo = new LoadInfo(myClassLoader,lastModified);
		loadInfo.setManager(manager);
		loadTimeMap.put(className, loadInfo);
	}

	//反射的方式创建BaseManager子类对象
	private static BaseManager newInstance(Class<?> loadClass) {
		
		try {
			return (BaseManager) loadClass.getConstructor(new Class[]{}).newInstance(new Object[]{});
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
}
